/*
 *  File : MultiValueAlphaNumericKey.java
 *  Created By : madhurt
 *  Created On : Oct 13, 2010
 *  Yahoo! 2010
 */
package com.gebogebo.key;

import java.util.Arrays;

/**
 *
 * @author madhurt
 */
public class MultiValueAlphaNumericKey implements MultiValueKey<Character> {

    private final int MAX_CHARS_PER_KEY;
    private final SingleValueKey<Character>[] singleValueKeys;
    private Character[] currentValue;

    public MultiValueAlphaNumericKey(int maxCharsPerKey) {
        MAX_CHARS_PER_KEY = maxCharsPerKey;
        singleValueKeys = new SingleValueKey[MAX_CHARS_PER_KEY];
        for (int i = 0; i < MAX_CHARS_PER_KEY; i++) {
            singleValueKeys[i] = new AlphaNumericKey();
        }
        currentValue = new Character[MAX_CHARS_PER_KEY];
    }

    public synchronized Character[] nextValue() throws ValueOverflowException {

        boolean valueOverflowOccured = false;
        for (int i = 0; i < singleValueKeys.length; i++) {
            try {
                Object nextValue = singleValueKeys[i].nextValue();
                //System.out.println("Obj from nextValue : " + nextValue);
                //key generated without overflow
                valueOverflowOccured = false;
                break;

            } catch (ValueOverflowException ex) {
                //System.out.println("VOE for "+ i);
                //this single key overflowed - reset it and move to the next one
                singleValueKeys[i].reset();
                valueOverflowOccured = true;
                continue;
            }
        }

        if (valueOverflowOccured) {
            throw new ValueOverflowException();

        } else {
            for (int i = MAX_CHARS_PER_KEY - 1, j = 0; i >= 0; i--, j++) {
                currentValue[j] = singleValueKeys[i].currentValue();
            }

            return currentValue;
        }
    }

    public synchronized Character[] reset() {
        for (int i = MAX_CHARS_PER_KEY - 1, j = 0; i >= 0; i++, j++) {
            currentValue[j] = singleValueKeys[i].reset();
        }

        return currentValue;
    }

    public synchronized Character[] currentValue() {
        return currentValue;
    }

    public Character[][] getkeySet() {
        Character[][] keys = new Character[MAX_CHARS_PER_KEY][];
        for (int i = 0; i < MAX_CHARS_PER_KEY; i++) {
            keys[i] = singleValueKeys[i].getkeySet();
        }

        return keys;
    }

    public static void main(String[] args) throws Exception {
        MultiValueAlphaNumericKey key = new MultiValueAlphaNumericKey(2);

        Character[][] keySet = key.getkeySet();
        for (Character[] cs : keySet) {
            System.out.println(Arrays.toString(cs));
        }
        System.out.println("============");
        for (int i = 0; i < keySet[0].length; i++) {
            for (int j = 0; j < keySet[1].length; j++) {
                Character[] c = key.nextValue();
                System.out.println("Got multi value " + Arrays.toString(c));
                assert c[0].equals(keySet[0][i]) : "Failed for 0" + ", " + i + ", got " + Arrays.toString(c);
                assert c[1].equals(keySet[1][j]) : "Failed for 1" + ", " + j + ", got " + Arrays.toString(c);
            }
        }

    }
}
